package com.trytech.mongoocrawler.client.transport.http.cookie;

import org.apache.commons.lang3.StringUtils;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * cookie的实际持有者，每个session对应一个
 */
public class HttpCookiesHolder {
    // 默认cookie Path
    public final static String DEFAULT_PATH = "/";
    private final static String seperator = "_";
    //cookie实体类的容器，key由path+name组成
    private static ConcurrentHashMap<String, HttpCookie> container = new ConcurrentHashMap<String, HttpCookie>();

    private String generateKey(String path, String name){
        return path+seperator+name;
    }
    /***
     * 获取单个cookie
     * @param path 匹配的路径
     * @param name cookie名
     * @return
     */
    public HttpCookie getCookie(String path, String name){
        return container.get(generateKey(path,name));
    }

    /***
     * 根据路径获取cookie
     * @param path 匹配的路径
     * @return
     */
    public List<HttpCookie> getCookie(String path){
        Iterator ite = container.keySet().iterator();
        List<HttpCookie> cookies = new LinkedList<HttpCookie>();
        while (ite.hasNext()){
            String key = ite.next().toString();
            if(key.startsWith(path)){
                cookies.add(container.get(key));
            }
        }
        return cookies.size()>0?cookies:null;
    }

    /***
     * 获取所有cookie
     * @return
     */
    public List<HttpCookie> getCookies(){
        return (List<HttpCookie>)container.values();
    }

    /***
     * 添加cookie
     * @param name
     * @param domain
     * @param expires
     * @param isSecure
     */
    public void addOrReplace(String name,String value, String domain, String expires, boolean isSecure){
        addOrReplace(name,value,null,domain,expires,isSecure);
    }

    /***
     * 添加cookie
     * @param name
     * @param path
     * @param domain
     * @param expires
     * @param isSecure
     */
    public void addOrReplace(String name,String value,  String path, String domain, String expires, boolean isSecure){
        if(StringUtils.isEmpty(path)){
            path=DEFAULT_PATH;
        }
        HttpCookie httpCookie = new HttpCookie();
        httpCookie.setName(name);
        httpCookie.setValue(value);
        httpCookie.setPath(path);
        httpCookie.setDomain(domain);
        httpCookie.setExpires(expires);
        httpCookie.setSecure(isSecure);
        container.put(generateKey(path,name),httpCookie);
    }

    /***
     * 移除cookie
     * @param path
     */
    public void delete(String path){
        Iterator ite = container.keySet().iterator();
        List<String> removedKeys = new LinkedList<String>();
        while (ite.hasNext()){
            String key = ite.next().toString();
            if(key.startsWith(path)){
                removedKeys.add(key);
            }
        }
        for(String removedKey : removedKeys){
            container.remove(removedKey);
        }
    }

    /***
     * 移除cookie
     * @param path
     * @param name
     */
    public void delete(String path, String name){
        String key = generateKey(path,name);
        container.remove(key);
    }

    public String toCookieString(){
        StringBuffer result = new StringBuffer();
        Iterator ite = container.values().iterator();
        while(ite.hasNext()){
            HttpCookie httpCookie = (HttpCookie) ite.next();
            result.append(httpCookie.getName());
            result.append("=");
            result.append(httpCookie.getValue());
            result.append(";");
        }
        return result.toString();
    }
}
